<?php
namespace Api\Model;

use Think\Model;

class LotteryModel extends ApiBaseModel
{

    /**
     * 检查角色当天是否已签到
     * @param int $userId 用户ID
     * @param  int $role 角色类型，1业主2师傅
     * @return mixed
     */ 
    public function checkSignIn($userId, $role)
    {
        $ret = array('sign'=>false, 'second'=>-1);
        if (!in_array($role, array(1,2))) {
            $this->setError(20002, '角色错误');
            return $ret;
        }

        $today = strtotime(date('Y-m-d'));
        $data['user_id'] = $userId;
        $data['role'] = $role;
        $data['add_time'] = array('gt', $today);
        $data['is_deleted'] = 0;

        $res = M('LotteryRecord')->where($data)->order('add_time desc')->find();
        if (!$res) { //没有签到记录
            if($role == 1){  //业主可以签到
                $ret['sign'] = true;
                $ret['second'] = 0;
                return $ret;
                //return true;
            }else{ //师傅需要判断活动时间
                $lottery = $this->checkLottery($role);
                $hour = date('H');
                if ($hour < $lottery['start_hour']) {
                    $this->setError(10002, '当天签到活动尚未开始');
                    $signStart = $today + $lottery['start_hour'] * 3600;
                    $nextSecond = $signStart - time();
                    $ret['second'] = $nextSecond;
                    return $ret;
                    // return false;
                }
                if ($hour >= $lottery['end_hour']) {
                    $this->setError(10003, '当天签到活动已经结束');
                    return $ret;
                    //return false;
                }
                //返回可以签到时间
                $ret['sign'] = true;
                $ret['second'] = 0;
                return $ret;
                //return 0;
            }
        }
        if ($role == 1) { //业主每天只能签到一次
            $this->setError(10004, '当天已签到');
            return $ret;
            //return false;
        }
        $lottery = $this->checkLottery($role);
        $nextSecond = false;
        $signStart = $today + $lottery['start_hour']  * 3600;//签到开始时间
        $signEnd   = $today + $lottery['end_hour'] * 3600;//签到结束时间
        
        while (true) {
            if (time() >= $signEnd or $signStart >= $signEnd) {//活动已结束
                $this->seterror(10006, '当天已完成所有签到');
                return $ret;
            }
            //获取下场开始时间
            $nextStart = $signStart + $lottery['period'] * 3600;
            if ($nextStart < time()) { //已过期，继续获取下一场
                $signStart = $nextStart;
                continue;
            }

            if ($res['add_time'] >= $signStart and $res['add_time'] < $nextStart) {
                //该场已签到
                //$nextSecond = $nextStart - time();
                if ($nextStart >= $signEnd) {//没有下一场 
                    $this->seterror(10006, '当天已完成所有签到');
                    return $ret;
                }
                //下次签到时间
                $nextSign = $res['add_time'] + $lottery['period'] * 3600;
                if ($nextSign >= $signEnd) { //有下一场，但时间不够
                    $this->seterror(10009, '当天已完成所有签到');
                    return $ret;
                }else{
                    $nextSecond = $nextSign - time();
                    $ret['second'] = $nextSecond;
                    $this->seterror(10005, '当场次您已签到，请等待下场次开始');
                    return $ret;
                }
                // $nextSecond = $res['add_time'] + $lottery['period'] * 3600 - time();
                // if ($nextStart == $signEnd) {
                //     $nextSecond = false;
                // }
                //break;
            }

            if($res['add_time'] < $signStart){
                //如果该场次签到已开始，用户还没签到，判断签到间隔时间是否已满
                $nextSign = $res['add_time'] + $lottery['period'] * 3600;
                if($nextSign >= $signEnd){//用户下次可签到时间大于当天活动结束时间
                    $this->seterror(10009, '当天已完成所有签到');
                    return $ret;
                    //$nextSecond = false;
                }elseif($nextSign > time()){ //用户下次可签到时间大于当前时间
                    $nextSecond = $nextSign - time();
                    $ret['second'] = $nextSecond;
                    $this->seterror(10008, '距离上次签到时间不足，请稍后再操作');
                    return $ret;
                }else{   //可以签到
                    $ret['sign'] = true;
                    $ret['second'] = 0;
                    return $ret;
                   // $nextSecond = 0;
                }
              //  break;
            }   
        }
    }

    /**
     * 检查当前是否有签到活动
     * @param  int $role 角色类型，1业主2师傅
     * @return [type]       [description]
     */
    public function checkLottery($role)
    {
        if (!in_array($role, array(1,2))) {
            $this->setError(20002, '角色错误');
            return false;
        }
        $cacheKey = '_LOTTERY_'.$role.'_';
        S(array('type'=>'redis'));
        if ($res = S($cacheKey)) {
            return $res;
        }
        $data['start_time'] = array('lt', time());
        $data['end_time']   = array('gt', time());
        $data['type']       = $role;
        $data['status']     = 1;

        $res = M('Lottery')->where($data)->find();
        if (!$res) {
            $this->setError(10001,'暂时没有签到活动');
            return false;
        }
        S(array('type'=>'redis','expire'=>$res['end_time']-time()));
        S($cacheKey, $res);
        return $res;
    }


    /**
     * 获取签到活动的奖品列表
     * @param  int $role 角色 1业主2师傅
     * @return mix       
     */
    public function getPrizeList($role)
    {
        $lottery = $this->checkLottery($role);
        if (!$lottery) {
            return false;
        }
        //读取缓存
        $cacheKey = '_LOTTERY_PRIZE_'.$role.'_';
        S(array('type'=>'redis'));
        if ($prize = S($cacheKey)) {
            return $prize;
        }
        $data['lottery_id'] = $lottery['id'];
        $data['type'] = $role;
        $data['is_deleted'] = 0;
        $prize = M('LotteryPrize')->field('id,name,amount,volume_id,surplus')
              ->where($data)->select();
        if ($prize) {
            //设置缓存
            S(array('type'=>'redis','expire'=>$lottery['end_time']-time()));
            S($cacheKey, $prize);
            return $prize;
        }else{
            $this->setError(20004, '奖品列表不存在');
            $lotteryKey = '_LOTTERY_'.$role.'_';
            S(array('type'=>'redis'));
            S($lotteryKey, null);
            return false;
        }

    }



     /**
     * 获取签到活动的奖品库存情况
     * @param  int $role 角色 1业主2师傅
     * @return mix       
     */
    public function getPrizeSku($role)
    {
        $lottery = $this->checkLottery($role);
        if (!$lottery) {
            return false;
        }
        //读取缓存
        $cacheKey = '_LOTTERY_PRIZE_SKU_'.$lottery['id'].'_'.$role.'_';
        S(array('type'=>'redis'));
        if ($prize = S($cacheKey)) {
            return $prize;
        }
        $data['lottery_id'] = $lottery['id'];
        $data['type'] = $role;
        $data['is_deleted'] = 0;
        if ($role == 1) {
            $start = strtotime(date('Y-m-d'));
            $end = $start + 86400;
        }else{
            //计算当场签到时间区间
            $today = strtotime(date('Y-m-d'));
            $signStart = $today + $lottery['start_hour'] * 3600;//签到开始时间
            $signEnd   = $today + $lottery['end_hour'] * 3600;//签到结束时间
            $start = $end = 0;
            while (true) {
                //获取下场开始时间
                $nextStart = $signStart + $lottery['period'] * 3600;
                if ($nextStart < time()) { //已过期，继续获取下一场
                    $signStart = $nextStart;
                    continue;
                }
                if (time() >= $signStart and time() < $nextStart) {
                    $start = $signStart;
                    $end = $nextStart;
                    break;
                }
            }
        }
        $sql = 'select p.id,p.name,p.amount,p.volume_id,p.sku,(select count(1) from '. 
               '__LOTTERY_RECORD__ where add_time >='.$start.' and add_time<'.$end.
               ' and prize_id = p.id and is_deleted = 0) as used from '.
               '__LOTTERY_PRIZE__ p WHERE p.lottery_id = '.$lottery['id'].' and '.
               'p.type = '.$role;
        $prize = M()->query($sql);
        if ($prize) {
            //设置缓存
            S(array('type'=>'redis','expire'=>$end-time()));
            S($cacheKey, array('prize'=>$prize,'end'=>$end));
            return array('prize'=>$prize,'end'=>$end);
        }else{
            $this->setError(20004, '奖品列表不存在');
            return false;
        }

    }
    /**
     * 签到抽奖
     * @param  int $userId 用户ID
     * @param  int $role   角色
     * @return mixed         
     */
    public function doLottery($userId, $role)
    {
        //$prizeList = $this->getPrizeList($role, true);
        $prizeList = $this->getPrizeSku($role);
        if (!$prizeList) {
            return false;
        }
        $surplus = 0;
        foreach ($prizeList['prize'] as $k => $v) {
            if ($v['sku'] > 0) {
                $prizeList['prize'][$k]['surplus'] = $v['sku'] - intval($v['used']);
                $prizeList['prize'][$k]['surplus'] < 0 and $prizeList['prize'][$k]['surplus'] = 0;
                if ($prizeList['prize'][$k]['surplus'] > 0) {
                    $surplus += $prizeList['prize'][$k]['surplus'];
                }
            }else{
                $prizeList['prize'][$k]['surplus'] = 0;
            }
            //$surplus += $v['surplus'];
        }
        $prize = array();
      //  var_dump($surplus);
        //所有奖品已经中完
        if ($surplus == 0) {
            $prize = array('id'=>'0','name'=>'谢谢参与','amount'=>'0.00','volume_id'=>'0');
        }else{
            $rand = rand(1, $surplus);
            foreach ($prizeList['prize'] as $k => $v) {
                if ($rand <= $v['surplus']) {
                    $prize = $v;
                    break;
                }else{
                    $rand -= $v['surplus'];
                }
            }
        }
        if (empty($prize)) {
            $this->setError(30001, '抽奖失败');
            return false;
        }else{
            $lottery = $this->checkLottery($role);
            if (!$lottery) {
                $this->setError(30002, '获取签到活动失败');
                return false; 
            }
            //开启事务
            $model = M();
            $model->startTrans();
            //插入抽奖记录
            $data['lottery_id'] = $lottery['id'];
            $data['user_id'] = $userId;
            $data['prize_id'] = $prize['id'];
            $data['prize_name'] = $prize['name'];
            $data['prize_amount'] = $prize['amount'];
            $data['role'] = $role;
            $data['is_deleted'] = 0;
            $data['add_time'] = time();
            $insert = M('LotteryRecord')->add($data);
           
            // //更新奖品库存
            // $update = true;
            // if ($prize['id']) {
            //     $condition['id'] = $prize['id'];
            //     $condition['surplus'] = array('gt', 0);
            //     $update = M('LotteryPrize')->where($condition)->setDec('surplus');
            // }
            //更新电子券信息
            $updateCoupon = true;
            if ($role == 1 and $prize['volume_id'] > 0) {
                //to do 插入用户记录
                $volume = M('volume')->find($prize['volume_id']);
                if ($volume) {
                    $coupon['user_id'] = $userId;
                    $coupon['total'] = $prize['amount'];
                    $coupon['category'] = $volume['category'];
                    $coupon['type'] = $volume['type'];
                    $coupon['min'] = $volume['min'];
                    $coupon['start_time'] = $volume['start_time'];
                    $coupon['end_time'] = $volume['end_time'];
                    $coupon['add_time'] = time();
                    $coupon['status'] = 1;
                    $coupon['volume_id'] = $volume['volume_id'];
                    $coupon['category_id'] = $volume['category_id'];
                    $coupon['get_scene'] = '签到活动';
                    $updateCoupon = M('volume_list')->add($coupon);
                }else{
                    $updateCoupon = false;
                } 
            }
            //更新师傅钱包与明细
            $updateUser = $insertDetail = true;
            if ($role == 2 and $prize['amount'] > 0) {
                $money = M('UserMoney')->where('user_id='.$userId)->find();
                $balance = $money['balance'] + $prize['amount'];
                $moenyData["balance"] = $balance;
                //更新余额
                $updateUser = M('UserMoney')->where('user_id='.$userId)->save($moenyData);
                if($updateUser!==false){
                    //新增账户明细
                    $mhMap["user_id"] = $userId;
                    $mhMap["type"] = 5;
                    $mhMap["total"] = $prize['amount'];
                    $mhMap["is_plus"] = 1;
                    $mhMap["balance"] = $balance;
                    $mhMap['flag'] = 5;
                    $mhMap['order_id'] = 0;
                    $mhMap['repair_order_id'] = 0;
                    $mhMap['renovation_order_id'] = 0;
                    $mhMap['protocol_id'] = 0;
                    $mhMap["add_time"] = time();
                    $mhMap["remark"] = "签到";
                    $insertDetail = M("MoneyHistory")->add($mhMap);
                }else{
                    $insertDetail = false;
                }
            }
            if($insert and $updateUser and $insertDetail){
                $model->commit();
                unset($prize['surplus']);
                unset($prize['used']);
                //todo更新缓存
                $this->updateSkuCache($prize, $lottery['id'], $role);
    
                $ret['prize'] = $prize;
                $ret['second'] = $this->getNextSecond($lottery);
                return $ret;
            }else{
                $model->rollback();
                $this->setError(30003, '插入抽奖记录失败');
                return false;
            }
            
        }
    }

    //刷新奖品库存
    private function updateSkuCache($prize, $lotteryId, $role)
    {
        if($prize['id'] <= 0){
            return false;
        }
        $cacheKey = '_LOTTERY_PRIZE_SKU_'.$lotteryId.'_'.$role.'_';
        if (!$cache = S($cacheKey)) {
            return false;
        }
        $prizeList = $cache['prize'];
        foreach ($prizeList as $k => $v) {
            if ($prize['id'] == $v['id']) {
                $prizeList[$k]['used'] ++;
                break;
            }
        }
        $end = $cache['end'];
        S($cacheKey, array('prize'=>$prizeList,'end'=>$end),array('type'=>'redis','expire'=>$end-time()));
    }

    private function getNextSecond($lottery)
    {
        $nextSecond = -1;
        //业主
        if ($lottery['type'] == 1) {
            return $nextSecond;
        }
        $today = strtotime(date('Y-m-d'));
        $signStart = $today + $lottery['start_hour'] * 3600;//签到开始时间
        $signEnd   = $today + $lottery['end_hour'] * 3600;//签到结束时间
        
        $nextSign = time() + $lottery['period'] * 3600;
        if ($nextSign >= $signEnd) {
            $nextSecond = -1;
        }else{
            $nextSecond = $lottery['period'] * 3600;
        }
        return $nextSecond;
        // while (true) {
        //     if ($signStart >= $signEnd) { //活动已结束
        //          break;
        //     } 
        //     //获取下场开始时间
        //     $nextStart = $signStart + $lottery['period'] * 3600;
        //     if ($nextStart < time()) { //已过期，继续获取下一场
        //         $signStart = $nextStart;
        //         continue;
        //     }

        //     if (time() >= $signStart and time() < $nextStart) {
        //         $signStart = $nextStart;
        //         //该场已签到
        //         $nextSecond = $nextStart - time();
        //         break;
        //     }

        //     if($res['add_time'] < $signStart){
        //         //如果该场次签到已开始，用户还没签到，则可以再签到
        //         $nextSecond = 0;//$signStart - $res['add_time'];
        //         break;
        //     }
        // }
        // if ($nextStart >= $signEnd) {
        //     $nextSecond = -1; //当前场次为当天最后一场
        // }
        // return $nextSecond;
    }

}
